package com.ruoyi.web.service;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import com.alibaba.fastjson.JSON;
import com.angel.mongodb.annotation.InitValue;
import com.mongodb.client.result.UpdateResult;
import com.ruoyi.common.core.service.impl.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.index.IndexOperations;
import org.springframework.data.mongodb.core.index.IndexResolver;
import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexResolver;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Set;

/**
 * 启动时将表初始化
 * 建索引
 * 初始化数据
 */
@Component
public class InitAfterStartup implements ApplicationListener<ApplicationReadyEvent> {
    @Autowired
    PackageUtil packageUtil;
    // 写链接(写到主库,可使用事务)
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private BaseService baseService;
    @Autowired
    MongoMappingContext mongoMappingContext;

    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        System.out.println("==========starting init db============");
        // 找到主程序包
        Set<Class<?>> set = ClassUtil.scanPackage(packageUtil.getMainPackage());
        for (Class<?> clazz : set) {
            Document document = clazz.getAnnotation(Document.class);
            if (document == null) {
                continue;
            }
            // 创建表
            if (!mongoTemplate.collectionExists(clazz)) {
                mongoTemplate.createCollection(clazz);
                System.out.println("创建了" + clazz.getSimpleName() + "表");
                insertData(clazz);
            } else {
                if ("sysUser".equalsIgnoreCase(clazz.getSimpleName()) && baseService.findAllCount(clazz).intValue() == 0) {
                    insertData(clazz);
                }
            }

            // 创建索引
            IndexOperations indexOps = mongoTemplate.indexOps(clazz);
            IndexResolver resolver = new MongoPersistentEntityIndexResolver(mongoMappingContext);
            resolver.resolveIndexFor(clazz).forEach(indexOps::ensureIndex);

            Field[] fields = ReflectUtil.getFields(clazz);
            for (Field field : fields) {
                // 获取注解
                if (field.isAnnotationPresent(InitValue.class)) {
                    InitValue defaultValue = field.getAnnotation(InitValue.class);
                    if (defaultValue.value() != null) {

                        // 更新表默认值
                        Query query = new Query();
                        query.addCriteria(Criteria.where(field.getName()).is(null));

                        Long count = mongoTemplate.count(query, clazz);
                        if (count > 0) {
                            Update update = new Update().set(field.getName(), defaultValue.value());
                            UpdateResult updateResult = mongoTemplate.updateMulti(query, update, clazz);

                            System.out.println(clazz.getSimpleName() + "表更新了" + updateResult.getModifiedCount() + "条默认值");
                        }
                    }
                }

            }

        }
    }

    private void insertData(Class<?> clazz) {
        File file = null;
        try {
            file = ResourceUtils.getFile("classpath:db");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        if (file.exists()) {
            File[] files = file.listFiles();
            if (files != null) {
                for (File childFile : files) {
//                    System.out.println(FileUtil.getName(childFile));
//                    System.out.println(FileUtil.getPrefix(childFile));
                    if (clazz.getSimpleName().equalsIgnoreCase(FileUtil.getPrefix(childFile))) {
                        String jsonStr = FileUtil.readString(childFile, "UTF-8");
                        List lists = JSON.parseArray(jsonStr, clazz);
                        mongoTemplate.insertAll(lists);
                    }
                }
            }
        }
    }
}
